#ifndef _BINARYLINKTREE_H_
#define _BINARYLINKTREE_H_
#include <iostream>
#define ElementType void*

class BinaryLinkTree
{
public:
    BinaryLinkTree();
    ~BinaryLinkTree();
    void Insert(ElementType element);
    void Remove(ElementType element);
    ElementType* Find(ElementType element);

    ElementType* FindByIndex(int index);

    void show();

    void SetCallbackCompareID(int (*CompareIDPtr)(ElementType,ElementType));
    void SetCallbackShowStudent(void (*ShowStudent)(ElementType));
    void SetCallbackSearchByIndex(int (*SeachID)(ElementType,int));

    
private:
    struct Node
    {   
        Node(ElementType element)
        {
            data = element;
            left = right = parent = nullptr;
        }
        ElementType data;
        Node *left;
        Node *right;
        Node *parent;
       
    };
    void PrevTravel(Node *node);
    void MidTravel(Node *node);
    void PostTravel(Node *node);
    Node* InsertNode(Node * node,ElementType element);
    int GetNodeHight(Node*node);
    int LeftRightDeviation(Node *node);

    ElementType* FindNode(Node*node,ElementType element);

    ElementType* FindNodeByIndex(Node *node,int index);

    Node *RemoveNode(Node *node,ElementType element);
    Node* GetMinNode(Node*node);

    Node*RotateLeft(Node *node);
    Node*RotateRight(Node *node);
    Node*RotateLeftRight(Node *node);
    Node*RotateRightLeft(Node *node);
    Node * root;

    int (*CompareID)(ElementType,ElementType);
    void (*ShowStu)(ElementType);
    int (*SearchIDByIndex)(ElementType,int);
};

using BLTree = BinaryLinkTree;




#endif